﻿using AJWPFAdmin.Core.Components.AJTable.ViewModels;
using AJWPFAdmin.Core.Enums;
using AJWPFAdmin.Core.Utils;
using AJWPFAdmin.Services.EF;
using MaterialDesignExtensions.Controls;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static AJWPFAdmin.Core.ExceptionTool;
using System.Windows.Controls;
using Masuit.Tools.Models;
using EntranceGuardManager.Modules.Main.Views;
using Microsoft.EntityFrameworkCore;
using AJWPFAdmin.Core.Models.EF.Tables;
using AJWPFAdmin.Core;
using AJWPFAdmin.Services.AppointAPI;
using Org.BouncyCastle.Asn1.X509;
using AJWPFAdmin.Core.Components.ViewModels;
using AJWPFAdmin.Core.Components.Views;

namespace EntranceGuardManager.Modules.Main.ViewModels
{

    public class DeviceListViewModel : BindableBase, INavigationAware
    {

        private AJTableFetchOptions _fetchOptions;

        public AJTableFetchOptions FetchOptions
        {
            get
            {
                return _fetchOptions;
            }
            set
            {
                SetProperty(ref _fetchOptions, value);
            }
        }

        private List<AJTableColumnItem> _columns;

        public List<AJTableColumnItem> Columns
        {
            get { return _columns; }
            set { SetProperty(ref _columns, value); }
        }

        private AJTableSearchFormConfig _formConfig;

        public AJTableSearchFormConfig FormConfig
        {
            get { return _formConfig; }
            set { SetProperty(ref _formConfig, value); }
        }


        private DelegateCommand<DataGridRow> _loadingRowCmd;
        public DelegateCommand<DataGridRow> LoadingRowCmd =>
            _loadingRowCmd ?? (_loadingRowCmd = new DelegateCommand<DataGridRow>(ExecuteLoadingRowCmd));

        void ExecuteLoadingRowCmd(DataGridRow row)
        {

        }

        private DelegateCommand<Device> _editCmd;
        public DelegateCommand<Device> EditCmd =>
            _editCmd ?? (_editCmd = new DelegateCommand<Device>(ExecuteEditCmd));

        void ExecuteEditCmd(Device parameter)
        {
            var @params = new DialogParameters
            {
                { "data", parameter },
                { "watchhouseOptions", _watchHouseOptions },
                { "passagewayOptions", _passagewayOptions },
            };
            _dialogSvc.ShowDialog(nameof(DeviceForm), @params, r =>
            {
                if (r.Result == ButtonResult.OK)
                {
                    FetchOptions.RequestRefresh(false);
                }
            });
        }


        private DelegateCommand<Device> _deleteCmd;
        public DelegateCommand<Device> DeleteCmd =>
            _deleteCmd ?? (_deleteCmd = new DelegateCommand<Device>(ExecuteDeleteCmd));

        async void ExecuteDeleteCmd(Device parameter)
        {
            var confirm = await CommonUtil.ShowConfirmDialogAsync(new ConfirmationDialogArguments
            {
                Title = "删除确认",
                Message = parameter.Synchronized ? $"该数据已和线上接口同步,是否继续删除?" : $"即将删除 {parameter.Name} ?"
            });

            if (confirm)
            {
                if (!parameter.OnlyMonitor && parameter.Synchronized)
                {
                    var result = await _appointSvc.API.UploadDeviceInfoAsync(new DeviceInfoParams
                    {
                        Device = parameter,
                        Operation = DataOperationType.移除
                    });
                    if (!result.Success)
                    {
                        AJCommonDialog.ShowDialog(new AJCommonDialogViewModel.AJCommonDialogParams
                        {
                            Title = $"{_appointSvc.API.KeyDescription} 设备信息同步接口提示",
                            Message = result.Message,
                            Detail = result.Data is Exception ex ? ex.StackTrace : string.Empty
                        });
                        return;
                    }
                }

                db.Devices.Remove(parameter);
                await db.SaveChangesAsync();

                FetchOptions.RequestRefresh(false);
            }
        }

        private ObservableCollection<AJTableFormSchemaItemOptions> _watchHouseOptions;
        public ObservableCollection<AJTableFormSchemaItemOptions> WatchHouseOptions
        {
            get { return _watchHouseOptions; }
            set
            {
                SetProperty(ref _watchHouseOptions, value);
            }
        }

        private ObservableCollection<AJTableFormSchemaItemOptions> _passagewayOptions;
        public ObservableCollection<AJTableFormSchemaItemOptions> PassagewayOptions
        {
            get { return _passagewayOptions; }
            set
            {
                SetProperty(ref _passagewayOptions, value);
            }
        }

        private IDialogService _dialogSvc;
        private DbService db;
        private AppointAPISvc _appointSvc;


        public DeviceListViewModel(DbService dbIns, AppointAPISvc appointAPISvc, IEventAggregator eventAggregator, IDialogService dialogSvc)
        {

            _dialogSvc = dialogSvc;
            _appointSvc = appointAPISvc;
            //eventAggregator.GetEvent<AJGlobalExceptionResolvedEvent>().Subscribe(() => Loading = false);

            FetchOptions = new AJTableFetchOptions
            {
                //ExportFileName = "车辆记录导出",
                Handle = async (formCfg, pageCfg) =>
                {

                    var typeFormSchema = FormConfig.Schemas.FirstOrDefault(p => p.Field == nameof(Device.Type));

                    var type = typeFormSchema.Value == null ? new short?()
                        : (short)((DeviceType)typeFormSchema.Value);

                    var houseFormSchema = FormConfig.Schemas
                        .FirstOrDefault(p => p.Field == nameof(Device.WatchhouseId));

                    var houseId = houseFormSchema.Value == null ? new long?() : (long)houseFormSchema.Value;

                    var passagewayFormSchema = FormConfig.Schemas
                        .FirstOrDefault(p => p.Field == nameof(Device.PassagewayId));

                    var passagewayId = passagewayFormSchema.Value == null
                        ? new long?() : (long)passagewayFormSchema.Value;

                    var dates = FormConfig.Schemas
                        .FirstOrDefault(p => p.Field == nameof(Device.CreateDate)).Value as ObservableCollection<DateTime?>;

                    var list = await db.Devices
                        .FilterEnum(type, p => p.Type)
                        .IfWhere(() => houseId.HasValue, p => p.WatchhouseId == houseId)
                        .IfWhere(() => passagewayId.HasValue, p => p.PassagewayId == passagewayId)
                        .BetweenInDates(dates.ToArray(), p => p.CreateDate)
                        .OrderByDescending(p => p.CreateDate)
                        .ToPagedListAsync(pageCfg.Current, pageCfg.PageSize);

                    if ((WatchHouseOptions?.Count).GetValueOrDefault() == 0)
                    {
                        var watchhouseOptions = await db.Watchhouses.AsNoTracking()
                        .Select(p => new AJTableFormSchemaItemOptions
                        {
                            Value = p.Id,
                            Label = p.Name
                        }).ToListAsync();

                        WatchHouseOptions = houseFormSchema.Options
                        = new ObservableCollection<AJTableFormSchemaItemOptions>(watchhouseOptions);
                    }

                    if ((PassagewayOptions?.Count).GetValueOrDefault() == 0)
                    {
                        var passagewayOptions = await db.Passageways.AsNoTracking()
                        .Select(p => new AJTableFormSchemaItemOptions
                        {
                            Value = p.Id,
                            Label = p.Name,
                            OtherData = p.WatchhouseId
                        }).ToListAsync();

                        PassagewayOptions = passagewayFormSchema.Options
                            = new ObservableCollection<AJTableFormSchemaItemOptions>(passagewayOptions);
                    }


                    foreach (var item in list.Data)
                    {
                        item.WatchhouseName = WatchHouseOptions
                            .FirstOrDefault(p => (long)p.Value == item.WatchhouseId)?.Label ?? "--";
                        item.PassagewayName = PassagewayOptions
                            .FirstOrDefault(p => (long)p.Value == item.PassagewayId)?.Label ?? "--";
                    }

                    return new AJTableFetchResult
                    {
                        Total = list.TotalCount,
                        HasNext = list.HasNext,
                        Rows = list.Data
                    };
                }
            };

            FormConfig = new AJTableSearchFormConfig
            {
                Schemas = new ObservableCollection<AJTableSearchFormSchema>
                {
                    new AJTableSearchFormSchema
                    {
                        Label = "设备类型",
                        Field = nameof(Device.Type),
                        Type = AJTableSchemaType.Input,
                        IsPopular = true,
                    },
                    new AJTableSearchFormSchema
                    {
                        Label = "出入口",
                        Field = nameof(Device.WatchhouseId),
                        Type = AJTableSchemaType.Select,
                        IsPopular = true,
                    },
                    new AJTableSearchFormSchema
                    {
                        Label = "道闸",
                        Field = nameof(Device.PassagewayId),
                        Type = AJTableSchemaType.Select,
                        IsPopular = true,
                    },
                    new AJTableSearchFormSchema
                    {
                        Labels = new string[]{ "创建开始日期","创建结束日期" },
                        Field = nameof(Device.CreateDate),
                        Type = AJTableSchemaType.RangePicker,
                        Value = new ObservableCollection<DateTime?>( new DateTime?[2]{null,null}),
                        IsPopular = true,
                    },
                },
                AdvFilterVisibility = System.Windows.Visibility.Collapsed,
                ExportVisibility = System.Windows.Visibility.Collapsed,
            };

            Columns = new List<AJTableColumnItem>
            {
                new AJTableColumnItem
                {
                    Title = "操作",
                    CustomTemplate = new AJTableCustomTemplate
                    {
                        Key = "TableOperatioin"
                    },
                    Fixed = AJTableColumnFixedType.Right,
                    Width = new DataGridLength(160),
                },
                new AJTableColumnItem
                {
                    DataIndex = nameof(Device.Name),
                    Title = "名称",
                },
                  new AJTableColumnItem
                {
                    DataIndex = nameof(Device.DevNo),
                    Title = "设备SN号",
                },
                new AJTableColumnItem
                {
                    DataIndex = nameof(Device.Type),
                    Title = "类型",
                    Formatter = new AJTableColumnFormatter
                    {
                        Handler = (val) =>
                        {
                            return ((DeviceType)val).ToString();
                        }
                    }
                },
                new AJTableColumnItem
                {
                    DataIndex = nameof(Device.WatchhouseName),
                    Title = "出入口",
                },
                new AJTableColumnItem
                {
                    DataIndex = nameof(Device.PassagewayName),
                    Title = "道闸",
                },
                new AJTableColumnItem
                {
                    DataIndex = nameof(Device.IP),
                    Title = "IP地址"
                },
                new AJTableColumnItem
                {
                    DataIndex = nameof(Device.Port),
                    Title = "端口号"
                },
                new AJTableColumnItem
                {
                    DataIndex = nameof(Device.SerialPort),
                    Title = "串口号",
                },
                new AJTableColumnItem
                {
                    DataIndex = nameof(Device.LoginName),
                    Title = "登录账户"
                },
                new AJTableColumnItem
                {
                    DataIndex = nameof(Device.LoginPassword),
                    Title = "登录密码"
                },
                new AJTableColumnItem
                {
                    DataIndex = nameof(Device.OnlyMonitor),
                    Title = "是否监控",
                    Formatter = new AJTableColumnFormatter
                    {
                        Handler = (val) =>
                        {
                            return (bool)val ? "是" : "否";
                        }
                    }
                },
                new AJTableColumnItem
                {
                    DataIndex = nameof(Device.Synchronized),
                    Title = "是否同步",
                    Formatter = new AJTableColumnFormatter
                    {
                        Handler = (val) =>
                        {
                            return (bool)val ? "已同步" : "未同步";
                        }
                    }
                },
                new AJTableColumnItem
                {
                    DataIndex = nameof(Device.CreateDate),
                    Title = "创建日期",
                    Formatter = new AJTableColumnFormatter
                    {
                        Handler = (val) =>
                        {
                            return ((DateTime)val).ToString("yyyy-MM-dd HH:mm:ss");
                        }
                    }
                }
            };

            db = dbIns;
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            //ExecuteGetListCmd();
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return false;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {

        }
    }
}
